package com.citywithincity.utils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Sequence {
	
	
	public static interface IdGenerator {
		
		/**
		 * 生成下一个不重复的流水号
		 * @return
		 */
		String next();
		
	}
	
	
	public static class DefaultIdGenerator extends BaseIdGenerater{

		public DefaultIdGenerator() {
			super("yyMMddHHmmss",3);
		}
		
	}
	
	public static class BaseIdGenerater implements IdGenerator, Runnable{
		private AtomicInteger value;
		
		private Thread thread;
		private String time;
		private ReentrantReadWriteLock lock;
		private DateFormat dateFormat;
		private int len;
		private long maxValue;
		
		public BaseIdGenerater(String dateFormat,int len){
			this.dateFormat = new SimpleDateFormat(dateFormat);
			this.len = len;
			this.maxValue = (long) Math.pow(10, len);
			
			time = this.dateFormat.format(new Date());
			lock = new ReentrantReadWriteLock();
			value = new AtomicInteger(1);
			thread = new Thread(this);
			thread.setDaemon(true);
			thread.start();
		}
		
		@Override
		public String next() {
			lock.readLock().lock();
			int v = value.getAndIncrement();
			String time = this.time;
			lock.readLock().unlock();
			
			if(v >= maxValue){
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					throw new RuntimeException();
				}
				return next();
			}
			
			StringBuffer sb = new StringBuffer().append(time);
			sb.append(StringUtils.leftPadZero(v, len));
			return sb.toString();
		}
		
		@Override
		public void run() {
			while (true){
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					break;
				}
				String now = dateFormat.format(new Date());
				if (!now.equals(time)){
					lock.writeLock().lock();
					time = now;
					value.set(1);
					lock.writeLock().unlock();
				}
			}
		}
		
	}
	
	
	
	static IdGenerator idGenerator = new BaseIdGenerater("yyMMddHHmmss",3);

	public static String getUniqueId() {
		return idGenerator.next();
	}
}
